﻿using System;
using System.IO;

namespace Faml.Frontend.Test
{
    public class TestApp
    {
        public static void Main(string[] args)
        {
            TestString("5+5", typeof(int));
            TestString("5.0 + 5", typeof(double));
            TestString("with A = 5, B = 10 A+B", typeof(int));
            TestString("with sum(A,B) = A+B sum(10,5.6)", typeof(double));
            TestString("max(5,5) + min(10.0, 15.0)", typeof(double));
            TestFile("average.faml", typeof(double));
            TestFile("transpose.faml", typeof(double[,]));
            TestFile("average2.faml", typeof(double));
        }

        private static void ReportFailure(string expression,Exception exc)
        {
            Console.WriteLine("*** FAML frontend test failed ***");
            Console.WriteLine("Expression:");
            Console.WriteLine(expression);
            Console.WriteLine("Reason:");
            Console.WriteLine(exc.Message);
        }

        public static void TestString(string expression, Type resultType)
        {
            try
            {
                MacroParser mp = new MacroParser(expression);
                mp.MoveNext();
                PrecompilerContext pc = new PrecompilerContext();
                Compiler cp = new Compiler();
                FamlExpression expr = cp.Precompile(mp);
                if(expr.Type != resultType)
                    throw new Exception(String.Format("Inferred type {0} does not match {1}",expr.Type,resultType));
                Console.WriteLine("Passed.");
            }
            catch (Exception exc)
            {
                ReportFailure(expression,exc);
            }
        }

        public static void TestFile(string path, Type resultType)
        {
            try
            {
                Stream s = File.Open(path, FileMode.Open);
                try
                {
                    MacroParser mp = new MacroParser(s);
                    mp.MoveNext();
                    PrecompilerContext pc = new PrecompilerContext();
                    Compiler cp = new Compiler();
                    FamlExpression expr = cp.Precompile(mp);
                    if (expr.Type != resultType)
                        throw new Exception(String.Format("Inferred type {0} does not match {1}", expr.Type, resultType));
                }
                finally
                {
                    s.Close();
                }
                Console.WriteLine("Passed.");
            }
            catch (Exception exc)
            {
                ReportFailure(File.ReadAllText(path),exc);
            }
        }
    }
}